using System;
using System.Collections.Generic;
using System.Text;

namespace OracleInternal.I18N
{
	internal class UTF16ConvUTFE : Conv
	{
		private static readonly byte[][] utf8m2utfe = new byte[16][]
		{
			new byte[16]
			{
				0,
				1,
				2,
				3,
				55,
				45,
				46,
				47,
				22,
				5,
				21,
				11,
				12,
				13,
				14,
				15
			},
			new byte[16]
			{
				16,
				17,
				18,
				19,
				60,
				61,
				50,
				38,
				24,
				25,
				63,
				39,
				28,
				29,
				30,
				31
			},
			new byte[16]
			{
				64,
				90,
				127,
				123,
				91,
				108,
				80,
				125,
				77,
				93,
				92,
				78,
				107,
				96,
				75,
				97
			},
			new byte[16]
			{
				240,
				241,
				242,
				243,
				244,
				245,
				246,
				247,
				248,
				249,
				122,
				94,
				76,
				126,
				110,
				111
			},
			new byte[16]
			{
				124,
				193,
				194,
				195,
				196,
				197,
				198,
				199,
				200,
				201,
				209,
				210,
				211,
				212,
				213,
				214
			},
			new byte[16]
			{
				215,
				216,
				217,
				226,
				227,
				228,
				229,
				230,
				231,
				232,
				233,
				173,
				224,
				189,
				95,
				109
			},
			new byte[16]
			{
				121,
				129,
				130,
				131,
				132,
				133,
				134,
				135,
				136,
				137,
				145,
				146,
				147,
				148,
				149,
				150
			},
			new byte[16]
			{
				151,
				152,
				153,
				162,
				163,
				164,
				165,
				166,
				167,
				168,
				169,
				192,
				79,
				208,
				161,
				7
			},
			new byte[16]
			{
				32,
				33,
				34,
				35,
				36,
				37,
				6,
				23,
				40,
				41,
				42,
				43,
				44,
				9,
				10,
				27
			},
			new byte[16]
			{
				48,
				49,
				26,
				51,
				52,
				53,
				54,
				8,
				56,
				57,
				58,
				59,
				4,
				20,
				62,
				255
			},
			new byte[16]
			{
				65,
				66,
				67,
				68,
				69,
				70,
				71,
				72,
				73,
				74,
				81,
				82,
				83,
				84,
				85,
				86
			},
			new byte[16]
			{
				87,
				88,
				89,
				98,
				99,
				100,
				101,
				102,
				103,
				104,
				105,
				106,
				112,
				113,
				114,
				115
			},
			new byte[16]
			{
				116,
				117,
				118,
				119,
				120,
				128,
				138,
				139,
				140,
				141,
				142,
				143,
				144,
				154,
				155,
				156
			},
			new byte[16]
			{
				157,
				158,
				159,
				160,
				170,
				171,
				172,
				174,
				175,
				176,
				177,
				178,
				179,
				180,
				181,
				182
			},
			new byte[16]
			{
				183,
				184,
				185,
				186,
				187,
				188,
				190,
				191,
				202,
				203,
				204,
				205,
				206,
				207,
				218,
				219
			},
			new byte[16]
			{
				220,
				221,
				222,
				223,
				225,
				234,
				235,
				236,
				237,
				238,
				239,
				250,
				251,
				252,
				253,
				254
			}
		};

		private static readonly byte[][] utfe2utf8m = new byte[16][]
		{
			new byte[16]
			{
				0,
				1,
				2,
				3,
				156,
				9,
				134,
				127,
				151,
				141,
				142,
				11,
				12,
				13,
				14,
				15
			},
			new byte[16]
			{
				16,
				17,
				18,
				19,
				157,
				10,
				8,
				135,
				24,
				25,
				146,
				143,
				28,
				29,
				30,
				31
			},
			new byte[16]
			{
				128,
				129,
				130,
				131,
				132,
				133,
				23,
				27,
				136,
				137,
				138,
				139,
				140,
				5,
				6,
				7
			},
			new byte[16]
			{
				144,
				145,
				22,
				147,
				148,
				149,
				150,
				4,
				152,
				153,
				154,
				155,
				20,
				21,
				158,
				26
			},
			new byte[16]
			{
				32,
				160,
				161,
				162,
				163,
				164,
				165,
				166,
				167,
				168,
				169,
				46,
				60,
				40,
				43,
				124
			},
			new byte[16]
			{
				38,
				170,
				171,
				172,
				173,
				174,
				175,
				176,
				177,
				178,
				33,
				36,
				42,
				41,
				59,
				94
			},
			new byte[16]
			{
				45,
				47,
				179,
				180,
				181,
				182,
				183,
				184,
				185,
				186,
				187,
				44,
				37,
				95,
				62,
				63
			},
			new byte[16]
			{
				188,
				189,
				190,
				191,
				192,
				193,
				194,
				195,
				196,
				96,
				58,
				35,
				64,
				39,
				61,
				34
			},
			new byte[16]
			{
				197,
				97,
				98,
				99,
				100,
				101,
				102,
				103,
				104,
				105,
				198,
				199,
				200,
				201,
				202,
				203
			},
			new byte[16]
			{
				204,
				106,
				107,
				108,
				109,
				110,
				111,
				112,
				113,
				114,
				205,
				206,
				207,
				208,
				209,
				210
			},
			new byte[16]
			{
				211,
				126,
				115,
				116,
				117,
				118,
				119,
				120,
				121,
				122,
				212,
				213,
				214,
				88,
				215,
				216
			},
			new byte[16]
			{
				217,
				218,
				219,
				220,
				221,
				222,
				223,
				224,
				225,
				226,
				227,
				228,
				229,
				93,
				230,
				231
			},
			new byte[16]
			{
				123,
				65,
				66,
				67,
				68,
				69,
				70,
				71,
				72,
				73,
				232,
				233,
				234,
				235,
				236,
				237
			},
			new byte[16]
			{
				13,
				74,
				75,
				76,
				77,
				78,
				79,
				80,
				81,
				82,
				238,
				239,
				240,
				241,
				242,
				243
			},
			new byte[16]
			{
				92,
				244,
				83,
				84,
				85,
				86,
				87,
				88,
				89,
				90,
				245,
				246,
				247,
				248,
				249,
				250
			},
			new byte[16]
			{
				48,
				49,
				50,
				51,
				52,
				53,
				54,
				55,
				56,
				57,
				251,
				252,
				253,
				254,
				255,
				159
			}
		};

		private static UTF16ConvUtility.ConvertToCharsDelegate<char> ConvertBytesToCharsInstance = ConvertBytesToCharsImpl;

		private static UTF16ConvUtility.ConvertToCharsDelegate<byte> ConvertBytesToUTF16Instance = ConvertBytesToUTF16Impl;

		private static UTF16ConvUtility.GetCharsLengthDelegate GetCharsLengthInstance = GetCharsLengthImpl;

		private static UTF16ConvUtility.GetBytesOffsetDelegate GetBytesOffsetInstance = GetBytesOffsetImpl;

		public override int MinBytesPerChar => 1;

		public override int MaxBytesPerChar => 4;

		internal UTF16ConvUTFE(int oracleId)
			: base(oracleId)
		{
		}

		private static int GetCharsLengthImpl(byte[] bytes, int byteOffset, int byteCount, ref int bytesCounted)
		{
			int num = byteOffset;
			int num2 = byteOffset + byteCount;
			int num3 = 0;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			bool flag = true;
			while (num < num2 && flag)
			{
				switch ((utfe2utf8m[high(bytes[num])][low(bytes[num])] >> 4) & 0xF)
				{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
					num3++;
					num++;
					break;
				case 12:
				case 13:
					if (num + 1 >= num2)
					{
						flag = false;
						bytesCounted = num - byteOffset;
					}
					else
					{
						num3++;
						num += 2;
					}
					break;
				case 14:
					if (num + 2 >= num2)
					{
						flag = false;
						bytesCounted = num - byteOffset;
					}
					else
					{
						num3++;
						num += 3;
					}
					break;
				case 15:
					if (num + 3 >= num2)
					{
						flag = false;
						bytesCounted = num - byteOffset;
					}
					else
					{
						num3++;
						num += 4;
					}
					break;
				default:
					num3++;
					num++;
					break;
				}
			}
			return num3;
		}

		private static int GetBytesOffsetImpl(byte[] bytes, int byteOffset, int byteCount, ref int charCount)
		{
			int num = byteOffset;
			int num2 = byteOffset + byteCount;
			int num3 = 0;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			bool flag = true;
			while (num < num2 && flag && num3 < charCount)
			{
				switch ((utfe2utf8m[high(bytes[num])][low(bytes[num])] >> 4) & 0xF)
				{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
					num3++;
					num++;
					break;
				case 12:
				case 13:
					if (num + 1 >= num2)
					{
						flag = false;
						break;
					}
					num3++;
					num += 2;
					break;
				case 14:
					if (num + 2 >= num2)
					{
						flag = false;
						break;
					}
					num3++;
					num += 3;
					break;
				case 15:
					if (num + 3 >= num2)
					{
						flag = false;
						break;
					}
					num3++;
					num += 4;
					break;
				default:
					num3++;
					num++;
					break;
				}
			}
			charCount = num3;
			return num - byteOffset;
		}

		public override int GetBytesOffset(byte[] bytes, int byteOffset, int byteCount, int charCount)
		{
			int charCount2 = charCount;
			return GetBytesOffsetImpl(bytes, byteOffset, byteCount, ref charCount2);
		}

		private static int ConvertBytesToCharsImpl(byte[] bytes, int offset, int count, char[] chars, int charOffset, ref int charCount, bool ccb)
		{
			int num = offset;
			if (num < 0)
			{
				num = 0;
			}
			int num2 = num + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = charOffset;
			if (num3 < 0)
			{
				num3 = 0;
			}
			int num4 = num3 + charCount;
			if (num4 > chars.Length)
			{
				num4 = chars.Length;
			}
			bool flag = true;
			while (num < num2 && num3 < num4 && flag)
			{
				byte b = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
				switch ((b >> 4) & 0xF)
				{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
					chars[num3++] = (char)(b & 0x7Fu);
					break;
				case 8:
				case 9:
					chars[num3++] = (char)(b & 0x1Fu);
					break;
				case 12:
				case 13:
				{
					if (num >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 0x1Fu);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						chars[num3++] = '\ufffd';
					}
					else
					{
						chars[num3++] = (char)((uint)(b << 5) | (b2 & 0x1Fu));
					}
					break;
				}
				case 14:
				{
					if (num + 1 >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 0xFu);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b3 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2) || !is101xxxxx(b3))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						chars[num3++] = '\ufffd';
					}
					else
					{
						chars[num3++] = (char)((uint)((b << 10) | ((b2 & 0x1F) << 5)) | (b3 & 0x1Fu));
					}
					break;
				}
				case 15:
				{
					if (num + 2 >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 1u);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b3 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b4 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2) || !is101xxxxx(b3) || !is101xxxxx(b4))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						chars[num3++] = '\ufffd';
					}
					else
					{
						chars[num3++] = (char)((uint)((b << 15) | ((b2 & 0x1F) << 10) | ((b3 & 0x1F) << 5)) | (b4 & 0x1Fu));
					}
					break;
				}
				default:
					if (!ccb)
					{
						throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
					}
					chars[num3++] = '\ufffd';
					break;
				}
			}
			charCount = num3 - charOffset;
			return num - offset;
		}

		public override int ConvertBytesToChars(byte[] bytes, int offset, int count, char[] chars, int charOffset, ref int charCount, bool ccb)
		{
			return ConvertBytesToCharsImpl(bytes, offset, count, chars, charOffset, ref charCount, ccb);
		}

		private static int ConvertBytesToUTF16Impl(byte[] bytes, int offset, int count, byte[] utfbytes, int utfOffset, ref int utfCount, bool ccb)
		{
			int num = offset;
			if (num < 0)
			{
				num = 0;
			}
			int num2 = num + count;
			if (num2 > bytes.Length)
			{
				num2 = bytes.Length;
			}
			int num3 = utfOffset;
			if (num3 < 0)
			{
				num3 = 0;
			}
			int num4 = num3 + utfCount;
			if (num4 > utfbytes.Length)
			{
				num4 = utfbytes.Length;
			}
			bool flag = true;
			while (num < num2 && num3 + 1 < num4 && flag)
			{
				byte b = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
				switch ((b >> 4) & 0xF)
				{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
					utfbytes[num3++] = (byte)(b & 0x7Fu);
					utfbytes[num3++] = 0;
					break;
				case 8:
				case 9:
					utfbytes[num3++] = (byte)(b & 0x1Fu);
					utfbytes[num3++] = 0;
					break;
				case 12:
				case 13:
				{
					if (num >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 0x1Fu);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						utfbytes[num3++] = 253;
						utfbytes[num3++] = byte.MaxValue;
					}
					else
					{
						char c = (char)((uint)(b << 5) | (b2 & 0x1Fu));
						utfbytes[num3++] = (byte)(c & 0xFFu);
						utfbytes[num3++] = (byte)((int)c >> 8);
					}
					break;
				}
				case 14:
				{
					if (num + 1 >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 0xFu);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b3 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2) || !is101xxxxx(b3))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						utfbytes[num3++] = 253;
						utfbytes[num3++] = byte.MaxValue;
					}
					else
					{
						char c = (char)((uint)((b << 10) | ((b2 & 0x1F) << 5)) | (b3 & 0x1Fu));
						utfbytes[num3++] = (byte)(c & 0xFFu);
						utfbytes[num3++] = (byte)((int)c >> 8);
					}
					break;
				}
				case 15:
				{
					if (num + 2 >= num2)
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						flag = false;
						num--;
						break;
					}
					b = (byte)(b & 1u);
					byte b2 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b3 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					byte b4 = utfe2utf8m[high(bytes[num])][low(bytes[num++])];
					if (!is101xxxxx(b2) || !is101xxxxx(b3) || !is101xxxxx(b4))
					{
						if (!ccb)
						{
							throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
						}
						utfbytes[num3++] = 253;
						utfbytes[num3++] = byte.MaxValue;
					}
					else
					{
						char c = (char)((uint)((b << 15) | ((b2 & 0x1F) << 10) | ((b3 & 0x1F) << 5)) | (b4 & 0x1Fu));
						utfbytes[num3++] = (byte)(c & 0xFFu);
						utfbytes[num3++] = (byte)((int)c >> 8);
					}
					break;
				}
				default:
					if (!ccb)
					{
						throw new DecoderFallbackException(I18nStringResourceManager.GetErrorMesg("FAIL_CONV_TO_UNICODE"));
					}
					if (num3 + 1 < num4)
					{
						utfbytes[num3++] = 253;
						utfbytes[num3++] = byte.MaxValue;
					}
					break;
				}
			}
			utfCount = num3 - utfOffset;
			return num - offset;
		}

		public override int ConvertBytesToUTF16(byte[] bytes, int offset, int count, byte[] utfbytes, int utfOffset, ref int utfCount, bool ccb)
		{
			return ConvertBytesToUTF16Impl(bytes, offset, count, utfbytes, utfOffset, ref utfCount, ccb);
		}

		public override int GetBytesLength(char[] chars, int charOffset, int charCount)
		{
			int num = charOffset;
			int num2 = charOffset + charCount;
			int num3 = 0;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			for (int i = num; i < num2; i++)
			{
				int num4 = chars[i];
				num3 = ((num4 > 31) ? ((num4 > 127) ? ((num4 > 1023) ? ((num4 > 16383) ? (num3 + 4) : (num3 + 3)) : (num3 + 2)) : (num3 + 1)) : (num3 + 1));
			}
			return num3;
		}

		public override int GetBytesLength(string chars, int charOffset, int charCount)
		{
			int num = charOffset;
			int num2 = charOffset + charCount;
			int num3 = 0;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			for (int i = num; i < num2; i++)
			{
				int num4 = chars[i];
				num3 = ((num4 > 31) ? ((num4 > 127) ? ((num4 > 1023) ? ((num4 > 16383) ? (num3 + 4) : (num3 + 3)) : (num3 + 2)) : (num3 + 1)) : (num3 + 1));
			}
			return num3;
		}

		public override int GetBytesLength(byte[] utf16Bytes, int utf16BytesOffset, int utf16BytesCount)
		{
			int num = utf16BytesOffset;
			int num2 = utf16BytesOffset + utf16BytesCount;
			int num3 = 0;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > utf16Bytes.Length)
			{
				num2 = utf16Bytes.Length;
			}
			for (int i = num; i < num2 - 1; i += 2)
			{
				int num4 = (utf16Bytes[i + 1] << 8) | utf16Bytes[i];
				num3 = ((num4 > 31) ? ((num4 > 127) ? ((num4 > 1023) ? ((num4 > 16383) ? (num3 + 4) : (num3 + 3)) : (num3 + 2)) : (num3 + 1)) : (num3 + 1));
			}
			return num3;
		}

		public override int ConvertCharsToBytes(char[] chars, int chars_offset, int chars_count, byte[] bytes, int bytes_begin, ref int bytes_count, bool bUseReplacementChar)
		{
			int num = chars_offset;
			int num2 = chars_offset + chars_count;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			if (bytes_begin < 0)
			{
				bytes_begin = 0;
			}
			int num3 = bytes_begin + bytes_count;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			int num4 = bytes_begin;
			int i;
			for (i = num; i < num2; i++)
			{
				if (num4 >= num3)
				{
					break;
				}
				int num5 = chars[i];
				int b;
				if (num5 <= 31)
				{
					b = num5 | 0x80;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 127)
				{
					bytes[num4++] = utf8m2utfe[high(num5)][low(num5)];
					continue;
				}
				if (num5 <= 1023)
				{
					if (num4 + 1 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3E0) >> 5) | 0xC0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 16383)
				{
					if (num4 + 2 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3C00) >> 10) | 0xE0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = ((num5 & 0x3E0) >> 5) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num4 + 3 >= num3)
				{
					break;
				}
				b = ((num5 & 0x8000) >> 15) | 0xF0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x7C00) >> 10) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x3E0) >> 5) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = (num5 & 0x1F) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
			}
			bytes_count = num4 - bytes_begin;
			return i - num;
		}

		public override int ConvertStringToBytes(string chars, int chars_offset, int chars_count, byte[] bytes, int bytes_begin, ref int bytes_count, bool bUseReplacementChar)
		{
			int num = chars_offset;
			int num2 = chars_offset + chars_count;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > chars.Length)
			{
				num2 = chars.Length;
			}
			if (bytes_begin < 0)
			{
				bytes_begin = 0;
			}
			int num3 = bytes_begin + bytes_count;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			int num4 = bytes_begin;
			int i;
			for (i = num; i < num2; i++)
			{
				if (num4 >= num3)
				{
					break;
				}
				int num5 = chars[i];
				int b;
				if (num5 <= 31)
				{
					b = num5 | 0x80;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 127)
				{
					bytes[num4++] = utf8m2utfe[high(num5)][low(num5)];
					continue;
				}
				if (num5 <= 1023)
				{
					if (num4 + 1 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3E0) >> 5) | 0xC0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 16383)
				{
					if (num4 + 2 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3C00) >> 10) | 0xE0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = ((num5 & 0x3E0) >> 5) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num4 + 3 >= num3)
				{
					break;
				}
				b = ((num5 & 0x8000) >> 15) | 0xF0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x7C00) >> 10) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x3E0) >> 5) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = (num5 & 0x1F) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
			}
			bytes_count = num4 - bytes_begin;
			return i - num;
		}

		public override int ConvertUTF16ToBytes(byte[] utf16Bytes, int utf16BytesOffset, int utf16BytesCount, byte[] bytes, int byteOffset, ref int byteCount, bool bUseReplacementChar = true)
		{
			int num = utf16BytesOffset;
			int num2 = utf16BytesOffset + utf16BytesCount;
			if (num < 0)
			{
				num = 0;
			}
			if (num2 > utf16Bytes.Length)
			{
				num2 = utf16Bytes.Length;
			}
			if (byteOffset < 0)
			{
				byteOffset = 0;
			}
			int num3 = byteOffset + byteCount;
			if (num3 > bytes.Length)
			{
				num3 = bytes.Length;
			}
			int num4 = byteOffset;
			int i;
			for (i = num; i < num2 - 1; i += 2)
			{
				if (num4 >= num3)
				{
					break;
				}
				int num5 = (utf16Bytes[i + 1] << 8) | utf16Bytes[i];
				int b;
				if (num5 <= 31)
				{
					b = num5 | 0x80;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 127)
				{
					bytes[num4++] = utf8m2utfe[high(num5)][low(num5)];
					continue;
				}
				if (num5 <= 1023)
				{
					if (num4 + 1 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3E0) >> 5) | 0xC0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num5 <= 16383)
				{
					if (num4 + 2 >= num3)
					{
						break;
					}
					b = ((num5 & 0x3C00) >> 10) | 0xE0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = ((num5 & 0x3E0) >> 5) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					b = (num5 & 0x1F) | 0xA0;
					bytes[num4++] = utf8m2utfe[high(b)][low(b)];
					continue;
				}
				if (num4 + 3 >= num3)
				{
					break;
				}
				b = ((num5 & 0x8000) >> 15) | 0xF0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x7C00) >> 10) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = ((num5 & 0x3E0) >> 5) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
				b = (num5 & 0x1F) | 0xA0;
				bytes[num4++] = utf8m2utfe[high(b)][low(b)];
			}
			byteCount = num4 - byteOffset;
			return i - num;
		}

		private static int high(int b)
		{
			return (b >> 4) & 0xF;
		}

		private static int low(int b)
		{
			return b & 0xF;
		}

		private static bool is101xxxxx(byte c)
		{
			return (c & 0xE0) == 160;
		}

		public override int ConvertBytesToChars(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount, char[] chars, int charOffset, ref int charCount, bool bUseReplacementChar)
		{
			return UTF16ConvUtility.ConvertArraySegListToCharsImpl(bytes, bytesOffset, bytesCount, chars, charOffset, ref charCount, bUseReplacementChar, ConvertBytesToCharsInstance);
		}

		public override int GetCharsLength(byte[] bytes, int byteOffset, int byteCount)
		{
			int bytesCounted = 0;
			return GetCharsLengthImpl(bytes, byteOffset, byteCount, ref bytesCounted);
		}

		public override int GetCharsLength(ArraySegment<byte> bytes, int bytesOffset, int bytesCount)
		{
			int bytesCounted = 0;
			return GetCharsLengthImpl(bytes.Array, bytes.Offset + bytesOffset, bytesCount, ref bytesCounted);
		}

		public override int GetCharsLength(IList<ArraySegment<byte>> bytes, int bytesOffset, int bytesCount)
		{
			return UTF16ConvUtility.GetCharsLengthListSegs(bytes, bytesOffset, bytesCount, GetCharsLengthInstance);
		}

		public override int GetBytesOffset(IList<ArraySegment<byte>> bytes, int charCount)
		{
			return UTF16ConvUtility.GetBytesOffsetListSegs(bytes, charCount, GetBytesOffsetInstance);
		}
	}
}
